<script setup lang="ts">
import {
  UploadFile,
  UploadFiles,
  UploadInstance,
  UploadRawFile,
} from "element-plus";
import to from "await-to-js";
import {
  postToOSS as postToOssApi,
  getOssAuth as getOssAuthApi,
} from "@/service/api/course/image/CoverApi.ts";
import {
  linkImg as linkImgApi,
  editLinkImg as editLinkImgApi,
} from "@/service/api/course/image/DetailApi.ts";
import UploadButton from "@/components/Upload/uploadButton.vue";
import { CourseTypeDetailNameMap } from "@/maps/course/image/courseDetailMap.ts";
import { ZoomIn } from "@element-plus/icons-vue";

const props = defineProps({
  /**
   * 对应的课程id
   */
  courseId: {
    type: String,
    required: true,
  },
  /**
   * 介绍图片的类型
   */
  detailType: {
    type: Number,
    required: true,
  },
  /**
   * 是否已经上传过这个类型的介绍图片
   */
  isLinked: {
    type: Boolean,
    required: true,
  },
  /**
   * 选择的文件列表
   */
  fileList: {
    type: Array,
    required: true,
  },
  isOperable: {
    type: Boolean,
    required: true,
  },
});

/**
 * 定义事件
 */
const emit = defineEmits(['update:modelValue']);

// const attrs = useAttrs();

/**
 * 介绍图片名称
 */
const detailName = CourseTypeDetailNameMap.get(props.detailType);

/**
 * 是否已经绑定
 */
const isRelinked = ref(false);

/**
 * 是否已经选择图片
 */
const isSelected = ref(false);
/**
 * 是否已经上传图片
 */
const isUploaded = ref(false);

/**
 * 上传组件中的文件列表
 */
// const fileList = ref([{url: props.linkedImageUrl}]);

/**
 * 选择的原始图片
 */
const originalDetailFile = ref<UploadRawFile>(<UploadRawFile>{});
/**
 * 上传组件元素
 */
const uploadEl = ref<UploadInstance>();

/**
 * 上传介绍图片请求参数原型
 */
const initCoverParams = {
  OSSAccessKeyId: "",
  callback: "",
  dir: "",
  expire: "",
  host: "",
  policy: "",
  service: "",
  signature: "",
  file: "",
  key: "",
};

/**
 * 上传介绍图片请求参数
 */
const coverParams = reactive({ value: { ...initCoverParams } });

/**
 * 关联介绍图片与课程的请求对象原型
 */
// 关联图片与课程的BO
const initLinkImgBO = {
  courseId: "",
  ossId: "",
  type: 1,
  orderNum: 0,
};

/**
 * 关联介绍图片与课程的请求对象
 */
const linkImgBO = reactive({ ...initLinkImgBO });

/**
 * 上传凭证
 */
const getOssAuthBO = reactive({
  originalFileName: "",
});

/**
 * 预览图片地址
 */
const previewImageUrl = ref("");

/**
 * 是否显示预览对话框
 */
const isPreviewDialogShow = ref(false);

/**
 * 选择图片
 *
 * @param uploadFile
 * @param uploadFiles
 */
const handleSelect = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
  console.log(uploadFile, uploadFiles);
  originalDetailFile.value = uploadFile.raw ?? <UploadRawFile>{};
  isSelected.value = true;
  isUploaded.value = false;
  emit("update:modelValue", true);
};

/**
 * 超过一张时触发，重选图片
 * @param files
 */
const handleExceed = (files: File[]) => {
  // 手动加入一个文件
  // 清除文件
  uploadEl.value?.clearFiles();
  // 再重新加入，触发change事件
  const file = files[0] as UploadRawFile;
  uploadEl.value?.handleStart(file);
};

/**
 * 处理上传图片
 */
const handleUpload = async () => {
  console.log("upload");
  const response = await to(getOssAuth(originalDetailFile.value.name));

  if (response) {
    const formData = new FormData();
    formData.append("key", coverParams.value.key);
    formData.append("OSSAccessKeyId", coverParams.value.OSSAccessKeyId);
    formData.append("policy", coverParams.value.policy);
    formData.append("signature", coverParams.value.signature);
    formData.append("x:structure", "structure");
    formData.append("success_action_status", "200"); // 上传成功返回的状态码，不设置则是204
    formData.append("callback", coverParams.value.callback);
    formData.append("file", originalDetailFile.value); // 一定在最后

    const res = await postToOssApi(formData);
    console.log(res);
    // 是否上传成功
    if (res.status === 200) {
      ElMessage({
        type: "success",
        message: "上传成功",
      });

      // 是否拿到上传的图片的id
      if (res.data.code === 200) {
        linkImgBO.courseId = props.courseId;
        linkImgBO.ossId = res.data.data.id;
        linkImgBO.type = props.detailType;
        const response =
          props.isLinked || isRelinked.value
            ? await editLinkImg()
            : await linkImg();
        if (response) {
          isUploaded.value = true;
          // isLinked.value = true;
          isRelinked.value = true;
          emit('update:modelValue', false);

          ElMessage({
            type: "success",
            message: "图片和课程绑定成功",
          });
        } else {
          ElMessage({
            type: "error",
            message: "图片和课程绑定失败",
          });
        }
      } else {
        ElMessage({
          type: "error",
          message: "无法获取上传文件的链接",
        });
      }
    } else {
      ElMessage({
        type: "error",
        message: "上传失败，请联系管理员",
      });
    }
  }
};

/**
 * 获取OSS上传凭证
 * @param originalFilename
 */
const getOssAuth = async (originalFilename: string): Promise<boolean> => {
  getOssAuthBO.originalFileName = originalFilename;
  const [err, res] = await to(getOssAuthApi(getOssAuthBO));
  console.log(res);
  if (!err) {
    coverParams.value = {
      OSSAccessKeyId: "",
      callback: "",
      dir: "",
      expire: "",
      file: "",
      host: "",
      key: "",
      policy: "",
      service: "",
      signature: "",
      ...res.data,
    };
    return true;
  }
  return false;
};

/**
 * 绑定课程跟介绍图片
 */
const linkImg = async (): Promise<boolean> => {
  const [err, res] = await to(linkImgApi(linkImgBO));
  if (!err) {
    console.log(res);
    return true;
  }
  return false;
};

/**
 * 修改课程绑定的介绍图片
 */
const editLinkImg = async (): Promise<boolean> => {
  const [err, res] = await to(editLinkImgApi(linkImgBO));
  if (!err) {
    console.log(res);
    return true;
  }
  return false;
};

/**
 * 查看已上传图片的
 * @param file
 */
const handlePreview = (file: UploadFile) => {
  previewImageUrl.value = file.url ?? "";
  isPreviewDialogShow.value = true;
};

/**
 * 关闭图片预览
 */
const handleClosePreview = () => {
  isPreviewDialogShow.value = false;
};

onMounted(() => {
  console.log(props.fileList);
});
</script>

<template>
  <div class="upload-cover-image">
    <el-upload
      v-if="isOperable"
      action="#"
      :accept="'image/png, image/jpeg'"
      list-type="picture-card"
      :limit="1"
      :auto-upload="false"
      :on-change="handleSelect"
      :on-exceed="handleExceed"
      :file-list="fileList"
      ref="uploadEl"
    >
      <!--          v-bind="attrs"-->

      <el-icon v-if="!isSelected && !isLinked">
        <el-tooltip content="选择图片" placement="top" :enterable="false">
          <el-button
            link
            type="primary"
            icon="UploadFilled"
            size="large"
            v-hasPermi="['course:course:edit']"
          ></el-button>
        </el-tooltip>
      </el-icon>
      <el-icon v-else>
        <el-tooltip content="重新选择" placement="top" :enterable="false">
          <el-button
            link
            type="primary"
            icon="Refresh"
            size="large"
            v-hasPermi="['course:course:edit']"
          ></el-button>
        </el-tooltip>
      </el-icon>

      <template #file="{ file }">
        <div>
          <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
          <span class="el-upload-list__item-actions">
            <span
              class="el-upload-list__item-preview"
              @click="handlePreview(file)"
            >
              <el-tooltip content="查看详情" placement="top" :enterable="false">
                <el-icon><ZoomIn /></el-icon>
              </el-tooltip>
            </span>
          </span>
        </div>
      </template>
    </el-upload>

    <div v-else>
      <div
        v-if="props.fileList.length && props.fileList.length > 0"
        style="width: 150px; height: 150px; border: 1px solid #333"
      >
        <img
          style="width: 100%; height: 100%; object-fit: scale-down"
          :src="(props.fileList[0] as UploadFile).url"
          alt=""
        />
      </div>
      <el-button
        v-if="props.fileList.length && props.fileList.length > 0"
        link
        @click="handlePreview(props.fileList[0] as UploadFile)"
        type="success"
        class="image-buttons-right"
      >
        查看详情
      </el-button>

      <el-empty v-else :image-size="150" description="未上传图片" />
    </div>

    <div class="image-buttons">
      <upload-button
        v-if="isOperable"
        :is-uploaded="isUploaded"
        :is-selected="isSelected"
        :is-linked="isLinked"
        @click="handleUpload"
      ></upload-button>
    </div>
  </div>

  <!--  预览对话框-->
<!--  <el-dialog v-model="isPreviewDialogShow" :title="detailName" :center="true">-->
<!--    <img w-full :src="previewImageUrl" alt="Preview Image" />-->
<!--  </el-dialog>-->

  <el-image-viewer
      v-if="isPreviewDialogShow"
      :url-list="[previewImageUrl]"
      teleported
      @close="handleClosePreview"
  />

</template>

<style scoped lang="scss">
.image-buttons {
  margin-top: 16px;
}

.image-buttons-right {
  margin-left: 16px;
}
</style>
